package com.iocup.keybastion.core.matching.impl;


import com.iocup.keybastion.common.AuthConstant;
import com.iocup.keybastion.context.WebContextHolder;
import com.iocup.keybastion.core.matching.Matcher;
import org.apache.commons.lang3.StringUtils;

import java.util.Set;
import java.util.stream.Collectors;

/**
 * Define how the CORS requests are authorized.
 *
 * @author Jerome Leleu
 * @since 4.0.0
 */
public class CorsMatcher implements Matcher {

    private String allowOrigin;

    private String exposeHeaders;

    private int maxAge = -1;

    private Boolean allowCredentials;

    private Set<AuthConstant.HTTP_METHOD> allowMethods;

    private String allowHeaders;


    public String getAllowOrigin() {
        return allowOrigin;
    }

    public CorsMatcher setAllowOrigin(final String allowOrigin) {
        this.allowOrigin = allowOrigin;
        return this;
    }

    public String getExposeHeaders() {
        return exposeHeaders;
    }

    public CorsMatcher setExposeHeaders(final String exposeHeaders) {
        this.exposeHeaders = exposeHeaders;
        return this;
    }

    public int getMaxAge() {
        return maxAge;
    }

    public CorsMatcher setMaxAge(final int maxAge) {
        this.maxAge = maxAge;
        return this;
    }

    public Boolean getAllowCredentials() {
        return allowCredentials;
    }

    public CorsMatcher setAllowCredentials(final Boolean allowCredentials) {
        this.allowCredentials = allowCredentials;
        return this;
    }

    public Set<AuthConstant.HTTP_METHOD> getAllowMethods() {
        return allowMethods;
    }

    public CorsMatcher setAllowMethods(final Set<AuthConstant.HTTP_METHOD> allowMethods) {
        this.allowMethods = allowMethods;
        return this;
    }

    public String getAllowHeaders() {
        return allowHeaders;
    }

    public CorsMatcher setAllowHeaders(final String allowHeaders) {
        this.allowHeaders = allowHeaders;
        return this;
    }


    @Override
    public boolean matches(WebContextHolder webContextHolder) {
        if (StringUtils.isEmpty(allowOrigin)) {
            throw new IllegalArgumentException("allowOrigin不能为空");
        }
        webContextHolder.setResponseHeader(AuthConstant.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, allowOrigin);

        if (StringUtils.isNotBlank(exposeHeaders)) {
            webContextHolder.setResponseHeader(AuthConstant.ACCESS_CONTROL_EXPOSE_HEADERS_HEADER, exposeHeaders);
        }

        if (maxAge != -1) {
            webContextHolder.setResponseHeader(AuthConstant.ACCESS_CONTROL_MAX_AGE_HEADER, "" + maxAge);
        }

        if (allowCredentials != null && allowCredentials) {
            webContextHolder.setResponseHeader(AuthConstant.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, allowCredentials.toString());
        }

        if (allowMethods != null) {
            final String methods = allowMethods.stream().map(Enum::toString).collect(Collectors.joining(", "));
            webContextHolder.setResponseHeader(AuthConstant.ACCESS_CONTROL_ALLOW_METHODS_HEADER, methods);
        }

        if (StringUtils.isNotBlank(allowHeaders)) {
            webContextHolder.setResponseHeader(AuthConstant.ACCESS_CONTROL_ALLOW_HEADERS_HEADER, allowHeaders);
        }
        return true;
    }
}
